﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Telerik.OpenAccess;
using System.Web.Security;
using AcademySystem.DAL.Helpers;
using Telerik.OpenAccess.FetchOptimization;

namespace AcademySystem.DAL
{
    public class AcademySystemDAO
    {
        public static IEnumerable<Course> GetAllCources()
        {
            AcademySystemEntities entities = new AcademySystemEntities();
            IEnumerable<Course> courses = entities.Courses;
            return courses;
        }

        public static AuthenticationResult GetAuthenticationResult(string username, string password)
        {
            var users = Membership.GetAllUsers();
            MembershipUser muser = Membership.GetUser(username);
            if (Membership.ValidateUser(username, password))
            {
                MembershipUser user = Membership.GetUser(username);
                AuthenticationResult result = new AuthenticationResult()
                {
                    IsAuthenticated = true,
                    UserId = user.ProviderUserKey.ToString()
                };
                return result;
            }

            return AuthenticationResult.Empty;
        }

        public static IEnumerable<Course> GetCources(int skip, int count)
        {
            AcademySystemEntities entities = new AcademySystemEntities();
            IEnumerable<Course> courses = entities.Courses.Skip(skip).Take(count);
            return courses;
        }

        public static IEnumerable<Course> GetTopCourses(int count)
        {
            AcademySystemEntities entities = new AcademySystemEntities();

            FetchStrategy fetchStategy = new FetchStrategy();
            fetchStategy.LoadWith<Course>(course => course.Subscriptions);
            entities.FetchStrategy = fetchStategy;

            IEnumerable<Course> courses = entities.Courses
                .OrderByDescending(course => course.Subscriptions.Count)
                .Take(count);
            return courses;
        }

        public static IEnumerable<Course> GetUserCourses(Guid userId)
        {
            AcademySystemEntities entities = new AcademySystemEntities();
            IEnumerable<Course> courses = entities.Courses
                .Where(couse => couse.CreatorUserID == userId);
            return courses;
        }

        public static IEnumerable<Subscription> GetUserSubscriptions(Guid userId)
        {
            AcademySystemEntities entities = new AcademySystemEntities();

            FetchStrategy fetchStrategy = new FetchStrategy();
            fetchStrategy.LoadWith<Subscription>(subscription => subscription.Course);
            entities.FetchStrategy = fetchStrategy;

            IEnumerable<Subscription> subscriptions = entities.Subscriptions
                .Where(subscription => subscription.SubscriborUserID == userId);
            return subscriptions;
        }

        #region Courses CRUD

        public static Course GetCourse(int courseId)
        {
            using (AcademySystemEntities context = new AcademySystemEntities())
            {
                Course courseFound = context.Courses.SingleOrDefault(course => course.CourseID == courseId);
                return courseFound;
            }
        }

        public static Course AddCourse(string title, Guid creatorId, 
            DateTime startDate,DateTime endDate, string information)
        {
            using (AcademySystemEntities context = new AcademySystemEntities())
            {
                Course course = new Course()
                {
                    Title = title,
                    CreatorUserID = creatorId,
                    StartDate = startDate,
                    EndDate = endDate,
                    Information = information
                };

                context.Add(course);
                context.SaveChanges();

                return course;
            }
        }

        public static bool UpdateCourse(int courseId, 
            DateTime startDate, DateTime endDate, string information)
        {
            using (AcademySystemEntities context = new AcademySystemEntities())
            {
                Course courseFound = context.Courses.SingleOrDefault(course => course.CourseID == courseId);

                if (courseFound == null)
                {
                    return false;
                }

                courseFound.StartDate = startDate;
                courseFound.EndDate = endDate;
                courseFound.Information = information;

                context.SaveChanges();

                return true;
            }
        }

        public static bool DeleteCourse(int courseId)
        {
            using (AcademySystemEntities context = new AcademySystemEntities())
            {
                Course courseFound = context.Courses.SingleOrDefault(course => course.CourseID == courseId);

                if (courseFound == null)
                {
                    return false;
                }
                context.Delete(courseFound);
                context.SaveChanges();
                return true;
            }
        }

        #endregion

        #region Subscriptions CRUD

        public static Subscription GetSubscription(int subscriptionId)
        {
            using (AcademySystemEntities context = new AcademySystemEntities())
            {
                Subscription subscriptionFound = context.Subscriptions.
                    SingleOrDefault(subscription => subscription.SubscriptionID == subscriptionId);
                return subscriptionFound;
            }
        }
        
        public static Subscription AddSubscription(Guid userId, int courseId)
        {
            using (AcademySystemEntities context = new AcademySystemEntities())
            {
                Subscription subsription = new Subscription()
                {
                    SubscriborUserID = userId,
                    CourseID = courseId,
                    SubscriptionDate = DateTime.Now
                };

                context.Add(subsription);
                context.SaveChanges();

                return subsription;
            }
        }

        public static bool DeleteSubscription(int subscriptionId)
        {
            using (AcademySystemEntities context = new AcademySystemEntities())
            {
                Subscription subscriptionFound = 
                    context.Subscriptions.SingleOrDefault(subscription => subscription.SubscriptionID == subscriptionId);

                if (subscriptionFound == null)
                {
                    return false;
                }

                context.Delete(subscriptionFound);
                context.SaveChanges();
                return true;
            }
        }

        public static void ToggleSubscription(Guid userId, int courseId)
        {
            using (AcademySystemEntities context = new AcademySystemEntities())
            {
                Subscription subscriptionFound = 
                    context.Subscriptions.SingleOrDefault(subscription => subscription.CourseID == courseId);

                if (subscriptionFound == null)
                {
                    AddSubscription(userId, courseId);
                }
                else
                {
                    context.Delete(subscriptionFound);
                    context.SaveChanges();
                }
            }
        }

        #endregion
    }
}
